package com.yudean.esb.plugins;

import com.yudean.esb.plugins.component.SQLAdapter;
import com.yudean.esb.plugins.component.SelfMappers;
import org.apache.ibatis.jdbc.SQL;
import org.apache.ibatis.session.ResultContext;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.SqlSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * 处理含有子表查询的数据内容。将子表的内容填充到返回结果集中去
 *
 * @author Lei Duan <duanlei#gdyd.com>
 * @version 1.0.0
 * @since 2013-10-25@09
 */
public class SubMapperResultHanlder implements ResultHandler {
    private final static Logger LOGGER = LoggerFactory.getLogger(SubMapperResultHanlder.class);
    private SelfMappers selfMappers;
    private List<Map<String, Object>> mapped = new ArrayList<Map<String, Object>>();
    private SqlSession session;
    private MappedResultHandler subTableResultHandler;
    private Set<String> keys = null;

    public SubMapperResultHanlder(SelfMappers mappers, SqlSession session) {
        this.session = session;
        this.selfMappers = mappers;
        //数据库列名集合 ESB_SERVICE_MAPPER TB_COL_NAME
        this.keys = this.selfMappers.getPrimaryMap().keySet();
    }

    @Override
    public void handleResult(ResultContext context) {
        final HashMap<String, Object> record = (HashMap<String, Object>) context.getResultObject();
        HashMap<String, Object> result = new HashMap<String, Object>();
        if (record != null) {
            Iterator<String> iterator = this.keys.iterator();
            while (iterator.hasNext()) {
                String dataCol = iterator.next();
                Object obj = record.get(dataCol);
                //用来处理数据类型
                String dataVal = DbTypeHandler.getValue(obj);
                String node = selfMappers.getPrimaryMap().get(dataCol);
                if (node == null) {
                    continue;
                }
                //属性 值
                result.put(node, dataVal);
            }
        }

        final Map<String, String> aliasMap = selfMappers.getAliasMap();
        if (aliasMap != null) {
            Set<String> keyset = aliasMap.keySet();
            Iterator<String> iterator = keyset.iterator();
            while (iterator.hasNext()) {
                final String aliasName = iterator.next();
                String subQuery =
                        new SQL() {
                            {
                                //选择所有字段
                                SELECT("*");
                                String subTableName = aliasMap.get(aliasName);
                                //子表
                                FROM(subTableName);
                                //子表END
                                Map<String, String> relationMap = selfMappers.getRelationMap().get(aliasName);
                                Map<String, String> subMap = selfMappers.getSubMap().get(aliasName);
                                // 获取子表关联关系
                                Set<String> subKeyset = relationMap.keySet();
                                Iterator<String> subIterator = subKeyset.iterator();
                                WHERE("1=1");
                                while (subIterator.hasNext()) {
                                    String subCol = subIterator.next();
                                    String fatherCol = relationMap.get(subCol);
                                    String subKeyVal = DbTypeHandler.getValue(record.get(fatherCol));
                                    String condition = subCol + " = '" + subKeyVal + "' ";
                                    AND();
                                    WHERE(condition);
                                }
                                subTableResultHandler = new MappedResultHandler(subMap);
                            }
                        }.toString();
                LOGGER.debug("handleResult():subQuery={{}}", subQuery);

                List<Map<String, Object>> subList = handleSubQuery(subQuery);
                if (subList == null) {
                    subList = Collections.emptyList();
                }
                result.put(aliasName, subList);
            }
        }
        mapped.add(result);
    }

    private List<Map<String, Object>> handleSubQuery(String sql) {
        SQLAdapter sqlAdapter = new SQLAdapter(sql);
        session.select("com.yudean.esb.mapper.erp.ComplexQueryMapper.querySql", sqlAdapter, subTableResultHandler);
        return subTableResultHandler.getResult();
    }

    public List<Map<String, Object>> getResult() {
        return mapped;
    }
}
